// -----------------------------------------------------------------------
//  <copyright file="ICommandRepository.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2022 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2022-10-29 17:40</last-date>
// -----------------------------------------------------------------------

namespace DaprPlus.Domain.Entity;

/// <summary>
/// 定义通用实体仓储功能
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface IRepository<TEntity> : IQueryRepository<TEntity> where TEntity : class, IEntity, IAggregateRoot
{
    /// <summary>
    /// 插入实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<TEntity> InsertAsync(TEntity entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 插入多个实体
    /// </summary>
    /// <param name="entities">实体对象集合</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<int> InsertAsync(ICollection<TEntity> entities, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新实体对象
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新多个实体对象
    /// </summary>
    /// <param name="entities">实体对象集合</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<int> UpdateAsync(ICollection<TEntity> entities, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量更新实体
    /// </summary>
    /// <param name="specification">查询规约</param>
    /// <param name="updateExpression">属性更新表达式</param>
    /// <param name="cancellationToken">异步取消标识</param>
    /// <returns>操作影响的行数</returns>
    Task<int> UpdateBatchAsync(ISpecification<TEntity> specification, Expression<Func<TEntity, TEntity>> updateExpression, CancellationToken cancellationToken = default);

    /// <summary>
    /// 异步删除指定编号的实体
    /// </summary>
    /// <param name="key">实体编号</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<int> DeleteAsync<TKey>(TKey key, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除实体对象
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<int> DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除实体对象
    /// </summary>
    /// <param name="entities">实体对象集合</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<int> DeleteAsync(ICollection<TEntity> entities, CancellationToken cancellationToken = default);
    
    /// <summary>
    /// 删除所有符合查询规约的实体
    /// </summary>
    /// <param name="specification">查询规约</param>
    /// <param name="cancellationToken"></param>
    /// <returns>操作影响的行数</returns>
    Task<int> DeleteBatchAsync(ISpecification<TEntity> specification, CancellationToken cancellationToken = default);

    /// <summary>
    /// 执行指定的SQL语句
    /// </summary>
    /// <param name="sql">执行的SQL语句</param>
    /// <param name="param">SQL参数</param>
    /// <returns></returns>
    Task<int> ExecuteSqlCommandAsync(string sql, object? param = null);

    /// <summary>
    /// 执行指定的格式化SQL语句
    /// </summary>
    /// <param name="sql">要执行的格式化SQL语句</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<int> ExecuteSqlCommandAsync(FormattableString sql, CancellationToken cancellationToken = default);
}
